#pragma once

#include "Sol9Types.h"
#include <math.h>
#include <stdlib.h>

namespace sol9
{
namespace core
{

#ifdef PI
#undef PI
#endif

	const f32 PI				= 3.14159265359f;
	const f32 HALF_PI			= PI / 2.0f;
	const f32 RECIPROCAL_PI		= 1.0f / PI;

	const f32 DEGTORAD			= PI / 180.0f;
	const f32 RADTODEG			= 180.0f / PI;

	__forceinline f32 deg2rad(const f32 degrees)
	{
		return DEGTORAD * degrees;
	}

	__forceinline f32 rad2deg(const f32 radians)
	{
		return RADTODEG * radians;
	}

#ifdef PI64
#undef PI64
#endif

	const f64 PI64				= 3.1415926535897932384626433832795028841971693993751;
	const f64 HALF_PI64			= PI64 / 2.0;
	const f64 RECIPROCAL_PI64	= 1.0 / PI64;

	const f64 DEGTORAD64		= PI64 / 180.0;
	const f64 RADTODEG64		= 180.0 / PI64;

	__forceinline f64 deg2rad(const f64& degrees)
	{
		return DEGTORAD64 * degrees;
	}

	__forceinline f64 rad2deg(const f64& radians)
	{
		return RADTODEG64 * radians;
	}

	template <typename T>
	__forceinline T clamp(const T& value, const T& low, const T& high)
	{
		return std::min(std::max(value, low), high);
	}

	template <typename T>
	__forceinline T saturate(const T& value)
	{
		return clamp(value, (T)0, (T)1);
	}

	template <typename T>
	__forceinline T lerp(const T& a, const T& b, const f32 t)
	{
		//t = clamp(t, 0.0f, 1.0f);
		//return (T)((a * (1.0f - t)) + (b * t));
		
		//return (T)(a + (b - a) * clamp(t, 0.0f, 1.0f));

		return (T)(saturate(t) * (b - a) + a);
	}

} // namespace core
} // namespace sol9